home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / processes / procdoggie / udialogutils.p < prev    next >
Encoding:
Text File  |  2000-09-28  |  26.6 KB  |  665 lines

  1. {
  2.     File:        UDialogUtils.p
  3.  
  4.     Contains:    This unit is an embryonic version of an alternative to the Dialog Manager.
  5.                 Why replace the Dialog Manager?  For dialogs with just a few basic items like
  6.                 some static text and some buttons, the Dialog Manager isn’t too bad.  It still
  7.                 doesn’t handle low-memory situations at all well nor does it handle cases in
  8.                 which some resources are missing with much grace, but a small dialog shouldn’t
  9.                 have too many problems with low-memory situations and clever memory
  10.                 management can avoid all problems, and missing resources is an anomalous
  11.                 situation.  The Dialog Manager exposes its problems once a dialog starts to
  12.                 get a bit complicated.  User items and controls become difficult to manage,
  13.                 and even something as simple as a static text item that’s in a different size
  14.                 or style becomes a major hassle to implement.  The ictb mechanism introduced
  15.                 on Color QuickDraw machines was supposed to make it easier to specify static
  16.                 and edit text styles, but this mechanism is so buggy that it’s useless in my
  17.                 opinion.  Another problem with the Dialog Manager is its slow performance when
  18.                 drawing items.  Technical Note #203 “Don’t Abuse the Managers” has many words
  19.                 of wisdom when it comes to the Dialog Manager, like don’t use it.
  20.     
  21.                 Of course, the usual reply we get to this is, “But ResEdit’s DITL editor makes
  22.                 arranging dialogs so easy!”  This is true, and I think it’s a compelling
  23.                 argument.  This also makes localization very easy, which isn’t a trivial
  24.                 concern.  But who said that only the Dialog Manager can read DITLs?  The
  25.                 structure of a DITL is very well-defined, and couldn’t possibly change without
  26.                 breaking every program that put up an alert box.  DITL resources aren’t that
  27.                 complicated, and your own program can read them as well as the Dialog
  28.                 Manager——better probably.
  29.     
  30.                 That’s what this unit does.  It reads in a DITL, creates an internal item list
  31.                 based on what it found in the DITL, then attaches this item list to the
  32.                 "items" field of a DialogRecord.  This unit also contains routines to draw the
  33.                 items and routines to set static text items.  And it does this while checking
  34.                 for errors; what a concept!
  35.     
  36.                 But, as I said, this unit is very embryonic.  The first time I tried this, I
  37.                 made it very complete, but I also made it much, much harder to use than the
  38.                 Dialog Manager.  So, I almost completely stripped it for the purposes of this
  39.                 sample application.  Now, it only handles static text items and buttons, and
  40.                 it no longer handles modal dialogs.  Eventually, I want to give this the full
  41.                 functionality of the real Dialog Manager.
  42.     
  43.                  One capability this unit has that the Dialog Manager doesn’t implement is
  44.                 style information for static text items.  I don’t mean one static text item
  45.                 with multiple text styles.  I mean different items can have different text
  46.                 styles.  Doing this through the Dialog Manager involves much more work than
  47.                 it should.  The way I do this while keeping the DITL structure is to use the
  48.                 four bytes used for a placeholder for handle or procedure pointer in Inside
  49.                 Macintosh I page 427.  If you want static text items displayed in the standard
  50.                 font, style, and justification, then just leave these four bytes set to 0.  If
  51.                 you want to specify the type face, style, size, and line justification, then
  52.                 each of these four bytes can hold each of these pieces of information.
  53.     
  54.                 The first byte holds a font index.  This isn’t a font number because, as
  55.                 Technical Note #191 “Font Names” says, it isn’t nice to save font numbers.
  56.                 This font index is an index into a STR# resource which contains the names of
  57.                 whatever fonts you want to use in this dialog.  For example, if the second
  58.                 string in the STR# resource is "Monaco", then a 2 placed into the font index
  59.                 field will cause the DrawDialogItems routine defined in this unit to display
  60.                 that static text item in Monaco.  The STR# resource should have a resource ID
  61.                 of 0.  This lets all dialog boxes use the same font list.  You can override
  62.                 this font list by specifying a STR# resource with an ID equal to the resource
  63.                 ID of the DITL being read.  In this way, you can provide a STR# resource ID 0
  64.                 that contains the default font list, and then provide special font lists for
  65.                 for specific DITLs.
  66.     
  67.                 The second byte holds the style (“face” according to QuickDraw) of the static
  68.                 text item.  This holds the same value as the Style type.  The third byte
  69.                 contains the point size of the static text.  The point size is limited to 255,
  70.                 which shouldn’t be a problem.  The last byte contains the justification of the
  71.                 static text.  -2 means left justification, -1 means right justification, 0
  72.                 means default justification, and 1 means center justification.
  73.  
  74.     Written by: Forrest Tanaka    
  75.  
  76.     Copyright:    Copyright © 1988-1999 by Apple Computer, Inc., All Rights Reserved.
  77.  
  78.                 You may incorporate this Apple sample source code into your program(s) without
  79.                 restriction. This Apple sample source code has been provided "AS IS" and the
  80.                 responsibility for its operation is yours. You are not permitted to redistribute
  81.                 this Apple sample source code as "Apple sample source code" after having made
  82.                 changes. If you're going to re-distribute the source, we require that you make
  83.                 it clear in the source that the code was descended from Apple sample source
  84.                 code, but that you've made changes.
  85.  
  86.     Change History (most recent first):
  87.                 7/27/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  88.                 
  89.  
  90. }
  91. UNIT UDialogUtils;
  92.  
  93. {[j=20/57/1$] Pasmat Options}
  94.  
  95.  
  96. INTERFACE
  97.  
  98.     USES
  99.         Dialogs
  100.         ;
  101.  
  102. (*******************************************************************************
  103. * Used Units
  104. *******************************************************************************)
  105.  
  106. (*******************************************************************************
  107. * Constants
  108. *******************************************************************************)
  109.  
  110.     CONST
  111.         kNoItem = -1; {No dialog item is applicable or end of dialog item list}
  112.  
  113.  
  114. (*******************************************************************************
  115. * Types
  116. *******************************************************************************)
  117.  
  118.     TYPE
  119.         (* Type information for static text items *)
  120.         TypeInfoRec = RECORD
  121.             typeFace:  Integer; {Font number of text}
  122.             typeSize:  Integer; {Font size of text}
  123.             textJust:  Integer; {Justification of text}
  124.             typeStyle: Style;   {Font style of text}
  125.         END;
  126.  
  127.  
  128. (*******************************************************************************
  129. * InstallDialogItems - Install a DITL into a dialog window
  130. *
  131. * This routine is called to install a DITL into the dialog window specified by
  132. * "aDialog".  The resource ID of the desired DITL is specified by "itemListNum".
  133. * InstallDialogItems returns noErr if the item list was successfully created and
  134. * attached to aDialog, otherwise, an operating system error code is returned.
  135. *******************************************************************************)
  136.  
  137.     FUNCTION InstallDialogItems (aDialog:     DialogPtr;
  138.                                  itemListNum: Integer): OSErr;
  139.  
  140.  
  141. (*******************************************************************************
  142. * SetStatTextItem - Set a static text dialog item to the specified text
  143. *
  144. * This routine sets the text of a static text item to the text pointed to by
  145. * "textPtr" and having the length "textLength".  "aDialog" is a pointer to the
  146. * dialog box that this is being done in, and "itemNum" is the item number of the
  147. * static text item to set.  If that item isn’t actually a static text item, then
  148. * nothing is done.  If there isn’t enough memory to put the text into the static
  149. * text item, then nothing is done.
  150. *******************************************************************************)
  151.  
  152.     PROCEDURE SetStatTextItem (aDialog:    DialogPtr;
  153.                                itemNum:    Integer;
  154.                                textPtr:    Ptr;
  155.                                textLength: Integer);
  156.  
  157.  
  158. (*******************************************************************************
  159. * GetStatTextFontInfo - Get font information for a static text item
  160. *
  161. * This routine gets the font information for the static text item with an item
  162. * number of "itemNum" in the dialog specified by "aDialog".  This font
  163. * information is returned in "typeInfo".  The the specified item isn’t a static
  164. * text item, then nothing is done.
  165. *******************************************************************************)
  166.  
  167.     PROCEDURE GetStatTextFontInfo (aDialog:      DialogPtr;
  168.                                    itemNum:      Integer;
  169.                                    VAR typeInfo: TypeInfoRec);
  170.  
  171.  
  172. (*******************************************************************************
  173. * DrawDialogItems - Draw all standard dialog items
  174. *
  175. * All standard dialog items in the dialog box pointed to by "aDialog" are drawn.
  176. *******************************************************************************)
  177.  
  178.     PROCEDURE DrawDialogItems (aDialog: DialogPtr);
  179.  
  180.  
  181. (*******************************************************************************
  182. * GetDialogItemRect - Get the item rectangle of a specified dialog item
  183. *
  184. * This routine gets the item rectangle of the dialog item in the dialog box
  185. * specified by "aDialog" and having an item number of "itemNum".  This rectangle
  186. * is returned in "itemRect".
  187. *******************************************************************************)
  188.  
  189.     PROCEDURE GetDialogItemRect (aDialog:      DialogPtr;
  190.                                  itemNum:      Integer;
  191.                                  VAR itemRect: Rect);
  192.  
  193.  
  194. (*******************************************************************************
  195. * DisposeDialogItems - Dispose of all dialog items in the specified dialog box
  196. *
  197. * This routine disposes of the memory used by all the dialog items in the dialog
  198. * box specified by "aDialog".  The item list itself is also deallocated.
  199. *******************************************************************************)
  200.  
  201.     PROCEDURE DisposeDialogItems (aDialog: DialogPtr);
  202.  
  203.  
  204. IMPLEMENTATION
  205.  
  206.     USES
  207.         Resources
  208.         ,TextUtils
  209.         ,Fonts
  210.         
  211.         (* Application *)
  212.         ,UEmergMem
  213.         ;
  214.  
  215.  
  216. (*******************************************************************************
  217. * Types
  218. *******************************************************************************)
  219.  
  220.     TYPE
  221.         TextStRec = PACKED RECORD
  222.             fontIndex: Byte;       {Index into STR# rsrc of font name for text}
  223.             statStyle: Style;       {Style of static text}
  224.             statSize:  Byte;       {Point size of static text}
  225.             statJust:  SignedByte; {Justification of static text}
  226.         END;
  227.  
  228.         DITLTmplRec = PACKED RECORD
  229.             pad0:        TextStRec;  {Text style for static text items}
  230.             displayRect: Rect;       {Rect in which to display item in wind coords}
  231.             itemType:    Byte;       {Type of item}
  232.             dataLen:     Byte;       {Length of item data}
  233.             CASE Integer OF
  234.                 0: (itemRes:  Integer);
  235.                 1: (itemText: PACKED ARRAY [0..239] OF Char)
  236.         END;
  237.         DITLTmplPtr = ^DITLTmplRec;
  238.  
  239.         ItemRec = RECORD
  240.             displayRect: Rect;        {Display item rect in window coords}
  241.             refCon:      LongInt;     {Used for anything client wants}
  242.             dismissor:   Boolean;     {True if the item is a dismissor}
  243.             CASE itemType: Integer OF {Code for item type or 0 if last item}
  244.                 0: (itemControl:  ControlHandle); {Handle to item control}
  245.                 1: (itemText:     Handle;         {Handle to text of static text}
  246.                      itemTypeInfo: TypeInfoRec)    {Type info for static text}
  247.         END;
  248.         ItemListArr = ARRAY [0..255] OF ItemRec;
  249.         ItemListPtr = ^ItemListArr;
  250.         ItemListHnd = ^ItemListPtr;
  251.  
  252.  
  253. {$S DialogUtils}
  254. (*******************************************************************************
  255. * Public: InstallDialogItems
  256. *
  257. * This routine is mainly a DITL-resource interpreter.  After loading the DITL
  258. * resource with a resource ID passed in itemListNum into memory, it reads the
  259. * information in it to build up an array of dialog items in an ItemListArr,
  260. * which is defined in the TYPE section of this source file.  This routine
  261. * allocates the item array and attaches it to the "items" field of the specified
  262. * DialogRecord.  Once the item array is filled, the DITL is no longer needed and
  263. * is made purgeable.
  264. *
  265. * Currently, this routine handles push buttons and static text fields.  Push
  266. * buttons are simply handled by calling NewControl.  The resulting ControlHandle
  267. * is placed into the itemControl field of the ItemRec.  For static text items,
  268. * a handle to the text is placed into itemText and the style information is
  269. * placed into the itemTypeInfo.
  270. *
  271. * Static text items are handled a little differently, and involves a change to
  272. * the DITL structure.  I’ve kept the size of the DITL the same as it ever was,
  273. * but the four bytes that are described as a “placeholder for handle or
  274. * procedure pointer” on page 427 of Inside Macintosh I are now interpreted by
  275. * InstallDialogItems to hold font information for static text items.  This font
  276. * information has the structure described by TextStRec which is declared in the
  277. * TYPE section of this source file.  This is a four-byte record that holds the
  278. * type face, type style, type size, and justification (really alignment) of the
  279. * static text item.  InstallDialogItems converts this into a TypeInfoRec
  280. * (declared in the UDialogUtils.p file) which is then placed into the item
  281. * array.  When DrawDialogItems is called, it draws static text items using this
  282. * font information.
  283. *
  284. * The TextStRec consists of four bytes.  The first bytes specifies the type
  285. * face to use for the static text.  It doesn’t specify the font number because
  286. * font numbers for a particular type face can vary from system to system.
  287. * Instead, this field holds an index into a STR# resource which holds a list of
  288. * font names.  The STR# resource must have a resource ID equal to the resource
  289. * ID of the DITL being read, that is, "itemListNum."
  290. *
  291. * The second byte specifies the style that the static text is meant to be drawn
  292. * in.  It holds the same value as the Style type.  The Style type is 16 bits
  293. * wide, so I declared this field as a Byte instead.  The third byte specifies
  294. * the size of text to use.  Of course, being a byte, it’s limited to a point
  295. * size of 255 points.  I didn’t think that’d be much of a problem, and you can
  296. * always draw the text yourself if you needed something larger.  The last byte
  297. * specifies the alignment of text in the static text item rectangle.  This field
  298. * can have the values teFlushRight, teFlushLeft, teFlushDefault, and teCenter.
  299. *
  300. * I wanted to keep the DITL mechanism so that Rez and particularly ResEdit could
  301. * still be used to edit the DITL, even though the Dialog Manager isn’t being
  302. * used with these kinds of dialogs.  Unfortunately, I had to redefine the Rez
  303. * DITL template so that it could take the static text font information, and
  304. * worse, ResEdit won’t edit DITLs that have non-zero values in the location that
  305. * I’m reading the font information.  So, keeping the DITL isn’t any particular
  306. * advantage over defining a completely new structure.  But, I’ll leave it this
  307. * ways for now.  There ARE other resource editors that might not be quite so
  308. * quick to criticize my DITLs.
  309. *
  310. * If all the dialog items were installed correctly, then noErr is returned.  If
  311. * any error happend, then the operating system result code is returned and the
  312. * dialog item list is disposed of, leaving aDialog unaffected.
  313. *******************************************************************************)
  314.  
  315.     FUNCTION InstallDialogItems (aDialog:     DialogPtr;
  316.                                  itemListNum: Integer): OSErr;
  317.  
  318.         TYPE
  319.             IntPtr = ^Integer;
  320.  
  321.         VAR
  322.             numItems:     Integer;       {Number of items in item list}
  323.             itemNum:      Integer;       {Item number of item we’re installing}
  324.             itemKind:     Integer;       {Type of the item}
  325.             fontNumber:   Integer;       {Font number of static text item}
  326.             ditlItemPtr:  DITLTmplPtr;   {Pointer to each item}
  327.             ditlList:     Handle;        {Handle to DITL resource}
  328.             itemList:     ItemListHnd;   {Handle to the item list}
  329.             aControl:     ControlHandle; {Handle to a control we’re installing}
  330.             aString:      Str255;        {String used for a couple of things}
  331.             staticText:   Handle;        {Handle to text for static text item}
  332.             dataLen:      Integer;       {Length of item data, rounded up to even}
  333.             doesDismiss:  Boolean;       {True if the item is a dismissor}
  334.  
  335.         PROCEDURE RecoverError (error: Integer);
  336.  
  337.         BEGIN
  338.             IF ditlList <> NIL THEN
  339.                 BEGIN
  340.                     HUnlock (ditlList);
  341.                     HPurge (ditlList)
  342.                 END;
  343.             IF itemList <> NIL THEN
  344.                 DisposeDialogItems (aDialog);
  345.             DialogPeek(aDialog)^.items := NIL;
  346.             InstallDialogItems := error;
  347.             EXIT (InstallDialogItems)
  348.         END;
  349.  
  350.     BEGIN
  351.         ditlList := NIL;
  352.         itemList := NIL;
  353.  
  354.         (* Grab the requested DITL resource *)
  355.         ditlList := GetResource ('DITL', itemListNum);
  356.         IF ditlList = NIL THEN
  357.             IF ResError = noErr THEN
  358.                 RecoverError (resNotFound)
  359.             ELSE
  360.                 RecoverError (ResError);
  361.  
  362.         (* Make sure we don’t lose it while we’re reading from it *)
  363.         HNoPurge (ditlList);
  364.  
  365.         (* Allocate item list; add 1 for flag record and 1 for numItems-1 adj *)
  366.         numItems := IntPtr(ditlList^)^;
  367.         itemList := ItemListHnd(NewHandleMargin (SIZEOF (ItemRec) * (numItems +
  368.                 2), kAllocApp, NOT kAllocClr));
  369.         IF itemList = NIL THEN
  370.             RecoverError (memFullErr);
  371.  
  372.         (* Fill with kNoItem items in case of error while building item list *)
  373.         FOR itemNum := 0 TO numItems + 1 DO
  374.             itemList^^ [itemNum].itemType := kNoItem;
  375.  
  376.         (* Put the item list into the dialog record *)
  377.         DialogPeek(aDialog)^.items := Handle(itemList);
  378.  
  379.         (* Point at the first item in the DITL *)
  380.         HLock (ditlList);
  381.         ditlItemPtr := DITLTmplPtr(ORD4(ditlList^) + SIZEOF (Integer));
  382.  
  383.         (* For each item in DITL, install into item list *)
  384.         FOR itemNum := 0 TO numItems DO
  385.             BEGIN
  386.                 (* Get the type of the item *)
  387.                 itemKind := ditlItemPtr^.itemType;
  388.  
  389.                 (* If itemDisable flag clear, item is a dismissor *)
  390.                 IF itemKind < 128 THEN
  391.                     doesDismiss := TRUE
  392.                 ELSE
  393.                     BEGIN
  394.                         doesDismiss := FALSE;
  395.                         itemKind := itemKind - 128
  396.                     END;
  397.  
  398.                 (* Grab the item information *)
  399.                 IF itemKind = ctrlItem + btnCtrl THEN
  400.                     BEGIN
  401.                         (* Copy control’s title to controlTitle *)
  402.                         BlockMoveData (@ditlItemPtr^.dataLen, @aString, ditlItemPtr^.
  403.                                 dataLen + 1);
  404.  
  405.                         (* Create the new control *)
  406.                         aControl := NewControl (aDialog, ditlItemPtr^.displayRect,
  407.                                 aString, TRUE, 0, 0, 0, pushButProc, 0);
  408.  
  409.                         (* Put the control’s handle into our item list *)
  410.                         itemList^^ [itemNum].itemType := itemKind;
  411.                         itemList^^ [itemNum].itemControl := aControl;
  412.  
  413.                         (* Bail if there’s not enough memory *)
  414.                         IF FailLowMemory (0) THEN
  415.                             RecoverError (memFullErr)
  416.                         ELSE IF aControl = NIL THEN
  417.                             IF (ResError = noErr) | (ResError = resNotFound) THEN
  418.                                 RecoverError (resNotFound)
  419.                             ELSE
  420.                                 RecoverError (ResError);
  421.  
  422.                         (* Put the control’s item number into the control’s refCon *)
  423.                         SetControlReference (aControl, itemNum)
  424.                     END
  425.                 ELSE IF itemKind = statText THEN
  426.                     BEGIN
  427.                         (* Allocate space for text *)
  428.                         staticText := NewHandleMargin (ditlItemPtr^.dataLen,
  429.                                 kAllocApp, NOT kAllocClr);
  430.  
  431.                         (* Put the control’s handle into our item list *)
  432.                         itemList^^ [itemNum].itemType := itemKind;
  433.                         itemList^^ [itemNum].itemText := staticText;
  434.  
  435.                         (* Bail if there’s not enough memory for the text *)
  436.                         IF staticText = NIL THEN
  437.                             RecoverError (memFullErr);
  438.  
  439.                         (* Copy DITL text to our text handle *)
  440.                         BlockMoveData (@ditlItemPtr^.itemText, staticText^, ditlItemPtr^.
  441.                                 dataLen);
  442.  
  443.                         (* Put a handle to the text into our item list *)
  444.                         aString [0] := CHR (0);
  445.                         IF ditlItemPtr^.pad0.fontIndex > 0 THEN
  446.                             BEGIN
  447.                                 GetIndString ((*<*)aString, itemListNum, ditlItemPtr^.
  448.                                         pad0.fontIndex);
  449.                                 IF aString [0] = CHR (0) THEN
  450.                                     GetIndString ((*<*)aString, 0, ditlItemPtr^.pad0.
  451.                                             fontIndex)
  452.                             END;
  453.                         IF aString [0] = CHR (0) THEN
  454.                             fontNumber := 0
  455.                         ELSE
  456.                             GetFNum (aString, (*<*)fontNumber);
  457.                         itemList^^ [itemNum].itemTypeInfo.typeFace := fontNumber;
  458.                         itemList^^ [itemNum].itemTypeInfo.typeSize := ditlItemPtr^.
  459.                                 pad0.statSize;
  460.                         itemList^^ [itemNum].itemTypeInfo.textJust := ditlItemPtr^.
  461.                                 pad0.statJust;
  462.                         itemList^^ [itemNum].itemTypeInfo.typeStyle :=
  463.                                 ditlItemPtr^.pad0.statStyle
  464.                     END
  465.                 ELSE
  466.                     itemList^^ [itemNum].itemType := itemKind;
  467.  
  468.                 (* Copy interesting characteristics to our item list *)
  469.                 WITH itemList^^ [itemNum] DO
  470.                     BEGIN
  471.                         (*WITH*)displayRect := ditlItemPtr^.displayRect;
  472.                         (*WITH*)refCon := 0;
  473.                         (*WITH*)dismissor := doesDismiss
  474.                     END;
  475.  
  476.                 (* Bump the pointer to the next item in the DITL *)
  477.                 dataLen := BAnd (ditlItemPtr^.dataLen + 1, $FFFE);
  478.                 ditlItemPtr := DITLTmplPtr(ORD4(@ditlItemPtr^.itemText) + dataLen)
  479.             END;
  480.  
  481.         (* Don’t need the dialog item list any more *)
  482.         HUnlock (ditlList);
  483.         HPurge (ditlList);
  484.     END;
  485.  
  486.  
  487. {$S DialogUtils}
  488. (*******************************************************************************
  489. * Public: SetStatTextItem
  490. *
  491. * The text of a static text item is specified by a handle to the text, so that
  492. * handle is resized to the new text length, if needed, and then the text is
  493. * simply BlockMoved in.
  494. *******************************************************************************)
  495.  
  496.     PROCEDURE SetStatTextItem (aDialog:    DialogPtr;
  497.                                itemNum:    Integer;
  498.                                textPtr:    Ptr;
  499.                                textLength: Integer);
  500.  
  501.         VAR
  502.             itemList:   ItemListHnd; {Handle to item list}
  503.             textHandle: Handle;      {Handle to the existing item text}
  504.  
  505.     BEGIN
  506.         (* Grab the item list from the dialog window’s refCon *)
  507.         itemList := ItemListHnd(DialogPeek(aDialog)^.items);
  508.  
  509.         (* If the item is indeed a static text item, then set it *)
  510.         IF itemList^^ [itemNum].itemType = statText THEN
  511.             BEGIN
  512.                 textHandle := itemList^^ [itemNum].itemText;
  513.                 IF NOT FailLowMemory (textLength) THEN
  514.                     BEGIN
  515.                         IF GetHandleSize (textHandle) <> textLength THEN
  516.                             SetHandleSize (textHandle, textLength);
  517.                         BlockMoveData (textPtr, textHandle^, textLength)
  518.                     END
  519.             END
  520.     END;
  521.  
  522.  
  523. {$S DialogUtils}
  524. (*******************************************************************************
  525. * Public: GetStatTextFontInfo
  526. *
  527. * Font information for a static text item is simply stored in its itemTypeInfo
  528. * field.  It’s a simple matter of copying this record into "typeInfo".
  529. *******************************************************************************)
  530.  
  531.     PROCEDURE GetStatTextFontInfo (aDialog:      DialogPtr;
  532.                                    itemNum:      Integer;
  533.                                    VAR typeInfo: TypeInfoRec);
  534.  
  535.         VAR
  536.             itemList: ItemListHnd; {Handle to item list}
  537.  
  538.     BEGIN
  539.         (* Grab the item list from the dialog window’s refCon *)
  540.         itemList := ItemListHnd(DialogPeek(aDialog)^.items);
  541.  
  542.         (* If the item is indeed a static text item, then set it *)
  543.         IF itemList^^ [itemNum].itemType = statText THEN
  544.             typeInfo := itemList ^^ [itemNum].itemTypeInfo
  545.     END;
  546.  
  547.  
  548. {$S DialogUtils}
  549. (*******************************************************************************
  550. * Public: DrawDialogItems
  551. *
  552. * The item list of a dialog box is stored in the "items" field of the
  553. * DialogRecord.  This routine loops through every dialog item and draws whatever
  554. * item types it understands.  Currently, this is static text items and icons.
  555. *******************************************************************************)
  556.  
  557.     PROCEDURE DrawDialogItems (aDialog: DialogPtr);
  558.  
  559.         VAR
  560.             itemNum:    Integer;     {Item number of item we’re installing}
  561.             itemList:   ItemListHnd; {Handle to the item list}
  562.             itemRect:   Rect;        {Rectangle of dialog item}
  563.             staticText: Handle;      {Handle to static text}
  564.  
  565.     BEGIN
  566.         (* Draw any static text items or icon items in the item list*)
  567.         itemList := ItemListHnd(DialogPeek(aDialog)^.items);
  568.         itemNum := 0;
  569.         WHILE itemList^^ [itemNum].itemType <> kNoItem DO
  570.             BEGIN
  571.                 IF itemList^^ [itemNum].itemType = statText THEN
  572.                     BEGIN
  573.                         (* Item is a static text item; call TETextBox if there’s text *)
  574.                         staticText := itemList^^ [itemNum].itemText;
  575.                         IF GetHandleSize (staticText) > 0 THEN
  576.                             BEGIN
  577.                                 TextFont (itemList^^ [itemNum].itemTypeInfo.typeFace);
  578.                                 TextSize (itemList^^ [itemNum].itemTypeInfo.typeSize);
  579.                                 TextFace (itemList^^ [itemNum].itemTypeInfo.typeStyle);
  580.                                 itemRect := itemList^^ [itemNum].displayRect;
  581.                                 HLock (staticText);
  582.                                 TETextBox (staticText^, GetHandleSize (staticText),
  583.                                         itemRect, itemList^^ [itemNum].itemTypeInfo.
  584.                                         textJust);
  585.                                 HUnlock (statictext)
  586.                             END
  587.                     END;
  588.                 itemNum := itemNum + 1
  589.             END
  590.     END;
  591.  
  592.  
  593. {$S DialogUtils}
  594. (*******************************************************************************
  595. * Public: GetDialogItemRect
  596. *
  597. * The item list of a dialog box is in the "items" field of the DialogRecord.
  598. * This handle is retrieved and the displayRect of the specified item into
  599. * "itemRect".
  600. *******************************************************************************)
  601.  
  602.     PROCEDURE GetDialogItemRect (aDialog:      DialogPtr;
  603.                                  itemNum:      Integer;
  604.                                  VAR itemRect: Rect);
  605.  
  606.         VAR
  607.             itemList: ItemListHnd; {Handle to item list}
  608.  
  609.     BEGIN
  610.         (* Grab the item list from the dialog window’s refCon *)
  611.         itemList := ItemListHnd(DialogPeek(aDialog)^.items);
  612.  
  613.         (* Copy the item’s display rectangle *)
  614.         itemRect := itemList^^ [itemNum].displayRect
  615.     END;
  616.  
  617.  
  618. {$S DialogUtils}
  619. (*******************************************************************************
  620. * Public: DisposeDialogItems
  621. *
  622. * A handle to the dialog box’s dialog item list is retrieved from the
  623. * DialogRecord’s "items" handle.  The type of each item is checked, and the
  624. * memory taken by that item is disposed of appropriately.
  625. *******************************************************************************)
  626.  
  627.     PROCEDURE DisposeDialogItems (aDialog: DialogPtr);
  628.  
  629.         VAR
  630.             itemNum:  Integer;     {Item number of item we’re installing}
  631.             itemList: ItemListHnd; {Handle to the item list}
  632.  
  633.     BEGIN
  634.         (* Grab the item list from the dialog window’s refCon *)
  635.         itemList := ItemListHnd(DialogPeek(aDialog)^.items);
  636.  
  637.         (* Starting at item 1, go through entire list and dispose of each item *)
  638.         IF itemList <> NIL THEN
  639.             BEGIN
  640.                 itemNum := 0;
  641.                 WHILE itemList^^ [itemNum].itemType <> kNoItem DO
  642.                     BEGIN
  643.                         WITH itemList^^ [itemNum] DO
  644.                             BEGIN
  645.                                 IF (*WITH*)itemType = ctrlItem + btnCtrl THEN
  646.                                     BEGIN
  647.                                         IF (*WITH*)itemControl <> NIL THEN
  648.                                             DisposeControl ((*WITH*)itemControl)
  649.                                     END
  650.                                 ELSE IF (*WITH*)itemType = statText THEN
  651.                                     BEGIN
  652.                                         IF (*WITH*)itemText <> NIL THEN
  653.                                             DisposeHandle ((*WITH*)itemText)
  654.                                     END
  655.                             END;
  656.  
  657.                         (* Go on to the next item in the item list *)
  658.                         itemNum := itemNum + 1
  659.                     END;
  660.                 DisposeHandle (Handle(itemList))
  661.             END
  662.     END;
  663.  
  664. END.
  665.